package ca.etsmtl.gti785.servlet;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.Socket;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.ArrayList;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.container.AsyncResponse;
import javax.ws.rs.container.Suspended;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import org.glassfish.jersey.server.JSONP;
import org.glassfish.jersey.server.ManagedAsync;
import org.json.JSONObject;

import com.google.gson.Gson;
import ca.etsmtl.gti785.servlet.Interfaces.IFileTransfer;
import ca.etsmtl.gti785.util.Fichier;
import ca.etsmtl.gti785.util.Constants;

/**
 * This class contains the call tree "/server/fileTransfer". It uses FileTransferJson from the client side to transfer a file/folder to another server. The GET returns the opened port to send the files.
 * @author Étienne Faucher, Pierre-Mary Bien-Aimé
 * @deprecated
 * @see FileTransfer
 */
@Path("/fileTransferksdfhsdf")
public class FileTransfert implements IFileTransfer {

	@Override
	@POST
	@ManagedAsync
	@Produces(MediaType.APPLICATION_JSON)
	public void startTransfer(@Context ServletContext context,
			@Suspended AsyncResponse asyncResponse,
			@Context HttpServletRequest request, String json) {
		FileTransferJson fichiers1 = FileTransferJson.fromJson(json);

		URL serveurDistant;
		HttpURLConnection conn;
		BufferedReader rd;
		String line;		
		String portNumberLine = "";
		int portNumber;
		
		//On a maintenant le fichier et le url : json.url et json.fileServer.
		try {
			serveurDistant = new URL(fichiers1.url);
			conn = (HttpURLConnection) serveurDistant.openConnection();
			conn.setRequestMethod("GET");
			rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
			while ((line = rd.readLine()) != null) {
				portNumberLine += line;
			}
			rd.close();

			JSONObject jsonPort = new JSONObject(portNumberLine);
			portNumber =  jsonPort.getInt("port");

	        TransfererFichiers(fichiers1.fileServer, serveurDistant.getHost(), portNumber);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}	
	}

	@Override
	@GET
	@Produces(MediaType.APPLICATION_JSON)
	public String getPortForTransfer() {
		return "{\"port\":" + String.valueOf(Constants.Socket_Server) + "}";
	}

	private boolean sendBySocket(Fichier fichier, String host, int port)
	{
			try 
			{
				System.out.println("Trying to send "  + fichier.path + " ...");
				File myFile = new File(Constants.Shared_Folder + fichier.path);
				if(myFile.exists())
				{
					Socket socket = new Socket(host, port);
					byte[] mybytearray = new byte[(int) myFile.length()];
					OutputStream os = socket.getOutputStream();
					ObjectOutputStream oos = new ObjectOutputStream(os);
					oos.writeObject(fichier.path);
					
					BufferedInputStream bis = new BufferedInputStream(new FileInputStream(myFile));
					bis.read(mybytearray, 0, mybytearray.length);
					os.write(mybytearray, 0, mybytearray.length);
					
					os.flush();
					oos.close();
					bis.close();
					socket.close();
					System.out.println("File sent !");
				}
			} 
			catch (UnknownHostException e) 
			{
				e.printStackTrace();
				return false;
			} 
			catch (IOException e) 
			{
				e.printStackTrace();
				return false;
			}
			
			return true;
	}

	private void TransfererFichiers(Fichier file, String url, int portNumber)
	{
		if(file.isFolder)
		{
			for(Fichier fichier: file.listFichiers)
			{
				TransfererFichiers(fichier, url, portNumber);
			}
		}
		else
		{
			sendBySocket(file, url, portNumber);
		}
	}
	
}

